"use strict";

var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _createSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/createSuper"));
var _classnames = _interopRequireDefault(require("classnames"));
var React = _interopRequireWildcard(require("react"));
var _configProvider = require("../config-provider");
var _defaultRenderEmpty = _interopRequireDefault(require("../config-provider/defaultRenderEmpty"));
var _context = require("../form/context");
var _LocaleReceiver = _interopRequireDefault(require("../locale/LocaleReceiver"));
var _en_US = _interopRequireDefault(require("../locale/en_US"));
var _statusUtils = require("../_util/statusUtils");
var _transKeys = require("../_util/transKeys");
var _warning = _interopRequireDefault(require("../_util/warning"));
var _list = _interopRequireDefault(require("./list"));
var _operation = _interopRequireDefault(require("./operation"));
var _search = _interopRequireDefault(require("./search"));
var _style = _interopRequireDefault(require("./style"));
const TransferFC = props => {
  const {
    prefixCls
  } = props;
  const [wrapSSR, hashId] = (0, _style.default)(prefixCls);
  return wrapSSR( /*#__PURE__*/React.createElement("div", {
    className: (0, _classnames.default)(props.className, hashId),
    style: props.style
  }, props.children));
};
let Transfer = /*#__PURE__*/function (_React$Component) {
  (0, _inherits2.default)(Transfer, _React$Component);
  var _super = (0, _createSuper2.default)(Transfer);
  function Transfer(props) {
    var _this;
    (0, _classCallCheck2.default)(this, Transfer);
    _this = _super.call(this, props);
    _this.separatedDataSource = null;
    _this.setStateKeys = (direction, keys) => {
      if (direction === 'left') {
        _this.setState(_ref => {
          let {
            sourceSelectedKeys
          } = _ref;
          return {
            sourceSelectedKeys: typeof keys === 'function' ? keys(sourceSelectedKeys || []) : keys
          };
        });
      } else {
        _this.setState(_ref2 => {
          let {
            targetSelectedKeys
          } = _ref2;
          return {
            targetSelectedKeys: typeof keys === 'function' ? keys(targetSelectedKeys || []) : keys
          };
        });
      }
    };
    _this.getLocale = (transferLocale, renderEmpty) => {
      const {
        locale = {}
      } = _this.props;
      return Object.assign(Object.assign(Object.assign({}, transferLocale), {
        notFoundContent: renderEmpty('Transfer')
      }), locale);
    };
    _this.moveTo = direction => {
      const {
        targetKeys = [],
        dataSource = [],
        onChange
      } = _this.props;
      const {
        sourceSelectedKeys,
        targetSelectedKeys
      } = _this.state;
      const moveKeys = direction === 'right' ? sourceSelectedKeys : targetSelectedKeys;
      const dataSourceDisabledKeysMap = (0, _transKeys.groupDisabledKeysMap)(dataSource);
      // filter the disabled options
      const newMoveKeys = moveKeys.filter(key => !dataSourceDisabledKeysMap.has(key));
      const newMoveKeysMap = (0, _transKeys.groupKeysMap)(newMoveKeys);
      // move items to target box
      const newTargetKeys = direction === 'right' ? newMoveKeys.concat(targetKeys) : targetKeys.filter(targetKey => !newMoveKeysMap.has(targetKey));
      // empty checked keys
      const oppositeDirection = direction === 'right' ? 'left' : 'right';
      _this.setStateKeys(oppositeDirection, []);
      _this.handleSelectChange(oppositeDirection, []);
      onChange === null || onChange === void 0 ? void 0 : onChange(newTargetKeys, direction, newMoveKeys);
    };
    _this.moveToLeft = () => _this.moveTo('left');
    _this.moveToRight = () => _this.moveTo('right');
    _this.onItemSelectAll = (direction, selectedKeys, checkAll) => {
      _this.setStateKeys(direction, prevKeys => {
        let mergedCheckedKeys = [];
        if (checkAll) {
          // Merge current keys with origin key
          mergedCheckedKeys = Array.from(new Set([].concat((0, _toConsumableArray2.default)(prevKeys), (0, _toConsumableArray2.default)(selectedKeys))));
        } else {
          const selectedKeysMap = (0, _transKeys.groupKeysMap)(selectedKeys);
          // Remove current keys from origin keys
          mergedCheckedKeys = prevKeys.filter(key => !selectedKeysMap.has(key));
        }
        _this.handleSelectChange(direction, mergedCheckedKeys);
        return mergedCheckedKeys;
      });
    };
    _this.onLeftItemSelectAll = (selectedKeys, checkAll) => _this.onItemSelectAll('left', selectedKeys, checkAll);
    _this.onRightItemSelectAll = (selectedKeys, checkAll) => _this.onItemSelectAll('right', selectedKeys, checkAll);
    _this.handleFilter = (direction, e) => {
      const {
        onSearch
      } = _this.props;
      const {
        value
      } = e.target;
      onSearch === null || onSearch === void 0 ? void 0 : onSearch(direction, value);
    };
    _this.handleLeftFilter = e => _this.handleFilter('left', e);
    _this.handleRightFilter = e => _this.handleFilter('right', e);
    _this.handleClear = direction => {
      const {
        onSearch
      } = _this.props;
      onSearch === null || onSearch === void 0 ? void 0 : onSearch(direction, '');
    };
    _this.handleLeftClear = () => _this.handleClear('left');
    _this.handleRightClear = () => _this.handleClear('right');
    _this.onItemSelect = (direction, selectedKey, checked) => {
      const {
        sourceSelectedKeys,
        targetSelectedKeys
      } = _this.state;
      const holder = direction === 'left' ? (0, _toConsumableArray2.default)(sourceSelectedKeys) : (0, _toConsumableArray2.default)(targetSelectedKeys);
      const index = holder.indexOf(selectedKey);
      if (index > -1) {
        holder.splice(index, 1);
      }
      if (checked) {
        holder.push(selectedKey);
      }
      _this.handleSelectChange(direction, holder);
      if (!_this.props.selectedKeys) {
        _this.setStateKeys(direction, holder);
      }
    };
    _this.onLeftItemSelect = (selectedKey, checked) => _this.onItemSelect('left', selectedKey, checked);
    _this.onRightItemSelect = (selectedKey, checked) => _this.onItemSelect('right', selectedKey, checked);
    _this.onRightItemRemove = selectedKeys => {
      const {
        targetKeys = [],
        onChange
      } = _this.props;
      _this.setStateKeys('right', []);
      onChange === null || onChange === void 0 ? void 0 : onChange(targetKeys.filter(key => !selectedKeys.includes(key)), 'left', (0, _toConsumableArray2.default)(selectedKeys));
    };
    _this.handleScroll = (direction, e) => {
      const {
        onScroll
      } = _this.props;
      onScroll === null || onScroll === void 0 ? void 0 : onScroll(direction, e);
    };
    _this.handleLeftScroll = e => _this.handleScroll('left', e);
    _this.handleRightScroll = e => _this.handleScroll('right', e);
    // eslint-disable-next-line class-methods-use-this
    _this.handleListStyle = (listStyle, direction) => {
      if (typeof listStyle === 'function') {
        return listStyle({
          direction
        });
      }
      return listStyle;
    };
    const {
      selectedKeys = [],
      targetKeys = []
    } = props;
    _this.state = {
      sourceSelectedKeys: selectedKeys.filter(key => !targetKeys.includes(key)),
      targetSelectedKeys: selectedKeys.filter(key => targetKeys.includes(key))
    };
    return _this;
  }
  (0, _createClass2.default)(Transfer, [{
    key: "getTitles",
    value: function getTitles(transferLocale) {
      var _a, _b;
      return (_b = (_a = this.props.titles) !== null && _a !== void 0 ? _a : transferLocale.titles) !== null && _b !== void 0 ? _b : [];
    }
  }, {
    key: "handleSelectChange",
    value: function handleSelectChange(direction, holder) {
      const {
        sourceSelectedKeys,
        targetSelectedKeys
      } = this.state;
      const {
        onSelectChange
      } = this.props;
      if (!onSelectChange) {
        return;
      }
      if (direction === 'left') {
        onSelectChange(holder, targetSelectedKeys);
      } else {
        onSelectChange(sourceSelectedKeys, holder);
      }
    }
  }, {
    key: "separateDataSource",
    value: function separateDataSource() {
      const {
        dataSource = [],
        rowKey,
        targetKeys = []
      } = this.props;
      const leftDataSource = [];
      const rightDataSource = new Array(targetKeys.length);
      const targetKeysMap = (0, _transKeys.groupKeysMap)(targetKeys);
      dataSource.forEach(record => {
        if (rowKey) {
          record = Object.assign(Object.assign({}, record), {
            key: rowKey(record)
          });
        }
        // rightDataSource should be ordered by targetKeys
        // leftDataSource should be ordered by dataSource
        if (targetKeysMap.has(record.key)) {
          rightDataSource[targetKeysMap.get(record.key)] = record;
        } else {
          leftDataSource.push(record);
        }
      });
      return {
        leftDataSource,
        rightDataSource
      };
    }
  }, {
    key: "render",
    value: function render() {
      return /*#__PURE__*/React.createElement(_LocaleReceiver.default, {
        componentName: "Transfer",
        defaultLocale: _en_US.default.Transfer
      }, contextLocale => /*#__PURE__*/React.createElement(_configProvider.ConfigConsumer, null, _ref3 => {
        let {
          getPrefixCls,
          renderEmpty,
          direction
        } = _ref3;
        return /*#__PURE__*/React.createElement(_context.FormItemInputContext.Consumer, null, _ref4 => {
          let {
            hasFeedback,
            status: contextStatus
          } = _ref4;
          const {
            prefixCls: customizePrefixCls,
            className,
            disabled,
            operations = [],
            showSearch = false,
            footer,
            style,
            listStyle = {},
            operationStyle,
            filterOption,
            render,
            children,
            showSelectAll,
            oneWay,
            pagination,
            status: customStatus
          } = this.props;
          const prefixCls = getPrefixCls('transfer', customizePrefixCls);
          const locale = this.getLocale(contextLocale, renderEmpty || _defaultRenderEmpty.default);
          const {
            sourceSelectedKeys,
            targetSelectedKeys
          } = this.state;
          const mergedStatus = (0, _statusUtils.getMergedStatus)(contextStatus, customStatus);
          const mergedPagination = !children && pagination;
          const {
            leftDataSource,
            rightDataSource
          } = this.separateDataSource();
          const leftActive = targetSelectedKeys.length > 0;
          const rightActive = sourceSelectedKeys.length > 0;
          const cls = (0, _classnames.default)(prefixCls, {
            [`${prefixCls}-disabled`]: disabled,
            [`${prefixCls}-customize-list`]: !!children,
            [`${prefixCls}-rtl`]: direction === 'rtl'
          }, (0, _statusUtils.getStatusClassNames)(prefixCls, mergedStatus, hasFeedback), className);
          const titles = this.getTitles(locale);
          const selectAllLabels = this.props.selectAllLabels || [];
          return /*#__PURE__*/React.createElement(TransferFC, {
            prefixCls: prefixCls,
            className: cls,
            style: style
          }, /*#__PURE__*/React.createElement(_list.default, Object.assign({
            prefixCls: `${prefixCls}-list`,
            titleText: titles === null || titles === void 0 ? void 0 : titles[0],
            dataSource: leftDataSource,
            filterOption: filterOption,
            style: this.handleListStyle(listStyle, 'left'),
            checkedKeys: sourceSelectedKeys,
            handleFilter: this.handleLeftFilter,
            handleClear: this.handleLeftClear,
            onItemSelect: this.onLeftItemSelect,
            onItemSelectAll: this.onLeftItemSelectAll,
            render: render,
            showSearch: showSearch,
            renderList: children,
            footer: footer,
            onScroll: this.handleLeftScroll,
            disabled: disabled,
            direction: direction === 'rtl' ? 'right' : 'left',
            showSelectAll: showSelectAll,
            selectAllLabel: selectAllLabels[0],
            pagination: mergedPagination
          }, locale)), /*#__PURE__*/React.createElement(_operation.default, {
            className: `${prefixCls}-operation`,
            rightActive: rightActive,
            rightArrowText: operations[0],
            moveToRight: this.moveToRight,
            leftActive: leftActive,
            leftArrowText: operations[1],
            moveToLeft: this.moveToLeft,
            style: operationStyle,
            disabled: disabled,
            direction: direction,
            oneWay: oneWay
          }), /*#__PURE__*/React.createElement(_list.default, Object.assign({
            prefixCls: `${prefixCls}-list`,
            titleText: titles === null || titles === void 0 ? void 0 : titles[1],
            dataSource: rightDataSource,
            filterOption: filterOption,
            style: this.handleListStyle(listStyle, 'right'),
            checkedKeys: targetSelectedKeys,
            handleFilter: this.handleRightFilter,
            handleClear: this.handleRightClear,
            onItemSelect: this.onRightItemSelect,
            onItemSelectAll: this.onRightItemSelectAll,
            onItemRemove: this.onRightItemRemove,
            render: render,
            showSearch: showSearch,
            renderList: children,
            footer: footer,
            onScroll: this.handleRightScroll,
            disabled: disabled,
            direction: direction === 'rtl' ? 'left' : 'right',
            showSelectAll: showSelectAll,
            selectAllLabel: selectAllLabels[1],
            showRemove: oneWay,
            pagination: mergedPagination
          }, locale)));
        });
      }));
    }
  }], [{
    key: "getDerivedStateFromProps",
    value: function getDerivedStateFromProps(_ref5) {
      let {
        selectedKeys,
        targetKeys,
        pagination,
        children
      } = _ref5;
      if (selectedKeys) {
        const mergedTargetKeys = targetKeys || [];
        return {
          sourceSelectedKeys: selectedKeys.filter(key => !mergedTargetKeys.includes(key)),
          targetSelectedKeys: selectedKeys.filter(key => mergedTargetKeys.includes(key))
        };
      }
      process.env.NODE_ENV !== "production" ? (0, _warning.default)(!pagination || !children, 'Transfer', '`pagination` not support customize render list.') : void 0;
      return null;
    }
  }]);
  return Transfer;
}(React.Component); // For high-level customized Transfer @dqaria
Transfer.List = _list.default;
Transfer.Operation = _operation.default;
Transfer.Search = _search.default;
var _default = Transfer;
exports.default = _default;